﻿namespace BlogsAPI.Interfaces
{
    using System;
    using System.Collections.Generic;

    #region Interface:IData

    /// <summary>
    /// Интерфейс для извлечения данных
    /// </summary>
    public interface IData
    {
        /// <summary>
        /// Получение ссылки на rss-блогера 
        /// По умолчанию, грузим блог и извлекаем ссылку
        /// </summary>
        /// <param name="userName">ник блогера</param>
        /// <param name="btype">Тип блога - сообщество или блог</param>
        /// <returns>Link on RSS feed</returns>
        string GetRssLink(string userName, BlogType btype);


        /// <summary>
        /// Получение ссылки на Foaf-блогера
        /// По умолчанию, грузим блог и извлекаем ссылку
        /// </summary>
        /// <param name="userName">ник блогера</param>
        /// <param name="btype">Тип блога - сообщество или блог</param>
        /// <returns>Link on Foaf feed</returns>
        /// <remarks><link rel="meta" type="application/rdf+xml" title="FOAF"
        /// href="http://username.livejournal.com/data/foaf" /></remarks>
        string GetFoafLink(string userName, BlogType btype);
    }

    #endregion

    #region Interface:IPosts

    /// <summary>
    /// Интерфейс для постинга
    /// </summary>
    public interface IPosts
    {
        /// <summary>
        /// Выкладывание записи в блоге
        /// </summary>
        /// <param name="user">Аккаунт блогера</param>
        /// <param name="bp">пост для блога</param>
        /// <returns></returns>
        PostResult MakePost(UserAccount user, BlogPost bp);

        /// <summary>
        /// Выкладывание записи в блоге
        /// </summary>
        /// <param name="user">Аккаунт блогера</param>
        /// <param name="bpOld">старый пост для блога</param>
        /// <param name="bpNew">новый пост для блога</param>
        /// <returns></returns>
        PostResult EditPost(UserAccount user, BlogPost bpOld, BlogPost bpNew);

        /// <summary>
        /// Сколько комментариев у поста
        /// </summary>
        /// <param name="bp">Важна только ссылка на пост</param>
        /// <returns>Число комментариев к записи</returns>
        int HowManyComments(BlogPost bp);

        /// <summary>
        /// Сколько ссылок на пост
        /// c помощью Яндекса
        /// </summary>
        /// <param name="bp">Важна только ссылка на пост</param>
        /// <returns>-1 - нет в индексе или ошибка</returns>
        int HowManyLinks(BlogPost bp);
    }

    #endregion

    #region Interface:IComments

    /// <summary>
    /// Интерфейс для комментов
    /// </summary>
    public interface IComments
    {
        /// <summary>
        /// Выкладывание записи в блоге
        /// </summary>
        /// <param name="user">Аккаунт блогера</param>
        /// <param name="cp">коммент для блога</param>
        /// <returns></returns>
        PostResult MakeComment(UserAccount user, CommentPost cp);
    }

    #endregion

    #region Interface:IFriends

    /// <summary>
    /// Интерфейс по добавление-удалению френдов
    /// </summary>
    public interface IFriends
    {        
        /// <summary>
        /// Определяем сколько френдов из списка есть в наших друзьях.
        /// Для сообщества - сколько людей из списка могут писать в сообщество
        /// </summary>
        /// <param name="userName">имя блога или сообщества</param>
        /// <param name="bt">Блог или Сообщество</param>
        /// <param name="friends">список друзей</param>
        /// <returns>Список тех, что читает блог или является членами сообщества</returns>
        List<string> IsFriended(String userName, BlogType bt, params string []friends);

        /// <summary>
        /// Интерфейс по добавлению френдов
        /// </summary>
        /// <param name="who">Имя аккаунта для которого меняем френдов</param>
        /// <param name="friends">Набор имен аккаунтов для френдования</param>
        /// <returns>NULL, если все хорошо, иначе ошибку ввиде Exception</returns>
        List<String> AddFriends(UserAccount who, params string[] friends);

        /// <summary>
        /// Интерфейс по удалению френдов
        /// </summary>
        /// <param name="who">Имя аккаунта для которого меняем френдов</param>
        /// <param name="friends">Набор имен аккаунтов для френдования</param>
        /// <returns>NULL, если все хорошо, иначе ошибку ввиде Exception</returns>
        List<String> DelFriends(UserAccount who, params string []friends);

        /// <summary>
        /// Функция вступления в сообщество.
        /// </summary>
        /// <param name="who">кто вступает</param>
        /// <param name="communityName">куда вступает</param>
        /// <returns>Ошибку, если таковая имела место</returns>
        Exception JoinCommunnity(UserAccount who, string communityName);

        /// <summary>
        /// Функция покидания сообщества.
        /// </summary>
        /// <param name="who">кто покидает</param>
        /// <param name="communityName">что покидает</param>
        /// <returns>Ошибку, если таковая имела место</returns>
        Exception LeaveCommunnity(UserAccount who, string communityName);
    }

    #endregion

    #region Interface:OpenId

    /// <summary>
    /// Некоторые популярные функции использования технологии OpenID на сайте в качестве клиента
    /// </summary>
    public interface IOpenIdLogin
    {
        /// <summary>
        /// Залогинится
        /// </summary>
        /// <param name="user">Аккаунт OpenID</param>
        /// <returns>Возвращает текст ошибки</returns>
        Boolean OpenIdLogin(UserOpenID user);

        /// <summary>
        /// Оставить комментарий от имени пользователя
        /// </summary>
        /// <param name="user">Аккаунт OpenID</param>
        /// <param name="cp"></param>
        /// <returns>Возвращает текст ошибки</returns>
        PostResult OpenIDComment(UserOpenID user, CommentPost cp);
    }

    /// <summary>
    /// Некоторые популярные функции использования технологии OpenID на сайте в сервера предоставления распределенной аутентификации
    /// </summary>
    public interface IOpenIdServer
    {
        /// <summary>
        /// проверка является ли запрос - запросом openID авторизации
        /// </summary>
        /// <param name="url">ссылка запроса</param>
        Boolean IsOpenIDRequest(string url);

        /// <summary>
        /// Передача стороннему сервису подтверждения о том, что в этом сайте мы залогинены
        /// </summary>
        /// <param name="url">ссылка запроса</param>
        /// <param name="user">аккаунт под которым логинимся</param>
        /// <returns>Ссылка для возвращения в сторонний сервис</returns>
        string GrantOpenID(string url, UserAccount user);

    }

    #endregion

    #region Interface:IQuote

    /// <summary>
    /// Интерфейс цитирования постов, в идеале нужно, чтобы упрощало цитирование и определение коли-ва процитировавших проретвитивших
    /// </summary>
    public interface IQuote
    {
        /// <summary>
        /// Получение сслки для цитирования по посту
        /// </summary>
        /// <param name="bp">Заполненный объект с постом</param>
        /// <returns>ссылку на страницу цитирования, NULL если цитирование не возможно</returns>
        String GetQuoteLink(BlogPost bp);
    }

    #endregion

    #region ISearchEngine

    /// <summary>
    /// Интерфейс полнотекстового поиска постов и комментов
    /// </summary>
    public interface ISearchEngine
    {
        /// <summary>
        /// Поиск упоминаний в блогосфере по тексту
        /// </summary>
        /// <param name="text">текст для поиска</param>
        /// <param name="fromDate">дата начиная с которой искать объекты, может быть нулом, тогде по максимуму!</param>
        /// <returns>массив постов удовлетворяющих поиску</returns>
        BlogPost[] SearchFor(String text, DateTime? fromDate);

        /// <summary>
        /// Поиск ссылающихся на определенный сайт
        /// </summary>
        /// <param name="link">сайт на который ссылаемся</param>
        /// <param name="fromDate">дата начиная с которой искать объекты, может быть нулом, тогде по максимуму!</param>
        /// <returns>массив постов удовлетворяющих поиску</returns>
        BlogPost[] SearchFor(Uri link, DateTime? fromDate);

        /// <summary>
        /// Получение сложно-параметрического запроса
        /// Типа, Любое из First и Любое из Second, но не Except
        /// </summary>
        /// <param name="First">Слова для поиска</param>
        /// <param name="Second">Слова для поиска 2</param>
        /// <param name="Except">Исключающие слова</param>
        /// <returns></returns>
        String FormQueryString(string[] First, string[] Second, string[] Except);
    }

    #endregion

    #region ILike

    /// <summary>
    /// Интерфейс полнотекстового поиска постов и комментов
    /// </summary>
    public interface ILike
    {
        /// <summary>
        /// Поиск значений лайков и прочего по ссылке
        /// </summary>
        /// <returns>массив данных</returns>
        Dictionary<string, int> GetLikes(Uri Link);
    }

    #endregion

    #region IVideoHost

    /// <summary>
    /// Интерфейс извлечения данных о видео
    /// </summary>
    public interface IVideoHost
    {
        /// <summary>
        /// Получение пары VideoData / BlogPost по ссылке
        /// </summary>
        Tuple<VideoData,BlogPost> GetVideoData(Uri link);

        /// <summary>
        /// Код для вставки в блог
        /// </summary>
        /// <param name="link">ссылка на видео</param>
        /// <param name="additional">Дополнительные данные необходимые для получения ссылки на видео</param>
        /// <returns>HTML code</returns>
        String FormEmbedCode(Uri link, String additional = null);
    }

    #endregion
}
